package com.vaadin.thomas.contenttool.ui;

import java.util.Locale;

import com.github.wolfie.blackboard.Blackboard;
import com.vaadin.Application;
import com.vaadin.service.ApplicationContext.TransactionListener;
import com.vaadin.thomas.contenttool.Config;
import com.vaadin.thomas.contenttool.ContentTool;
import com.vaadin.thomas.contenttool.ui.events.LangChangedEvent;
import com.vaadin.thomas.contenttool.ui.events.LangChangedListener;
import com.vaadin.thomas.contenttool.ui.events.LogoutInternalEvent;
import com.vaadin.thomas.contenttool.ui.events.LogoutInternalListener;
import com.vaadin.thomas.contenttool.ui.events.MenuFilterEvent;
import com.vaadin.thomas.contenttool.ui.events.MenuFilterListener;
import com.vaadin.thomas.contenttool.ui.events.MenuFragmentSelectedEvent;
import com.vaadin.thomas.contenttool.ui.events.MenuFragmentSelectedListener;
import com.vaadin.thomas.contenttool.ui.events.MenuTagSelectedEvent;
import com.vaadin.thomas.contenttool.ui.events.MenuTagSelectedListener;
import com.vaadin.thomas.contenttool.ui.events.PreviewCommittedEvent;
import com.vaadin.thomas.contenttool.ui.events.PreviewCommittedListener;
import com.vaadin.thomas.contenttool.ui.events.TagsChangedEvent;
import com.vaadin.thomas.contenttool.ui.events.TagsChangedListener;
import com.vaadin.thomas.contenttool.ui.events.ValueAddedEvent;
import com.vaadin.thomas.contenttool.ui.events.ValueAddedListener;
import com.vaadin.thomas.contenttool.ui.events.VersionChangedEvent;
import com.vaadin.thomas.contenttool.ui.events.VersionChangedListener;
import com.vaadin.ui.HorizontalSplitPanel;
import com.vaadin.ui.VerticalLayout;
import com.vaadin.ui.themes.Reindeer;

/**
 * Main class for ContentTool Admin UI. Takes care of all operations in the
 * Admin UI, except for Exceptions.
 * 
 * @author Thomas Mattsson / Vaadin OY
 */
public class AdminMainLayout extends VerticalLayout implements
		TransactionListener, LogoutInternalListener {

	private static final long serialVersionUID = -8646362151634037627L;

	private static ThreadLocal<Blackboard> blackboard = new ThreadLocal<Blackboard>();
	protected Blackboard bb;
	private static ThreadLocal<ContentTool> contenttool = new ThreadLocal<ContentTool>();
	protected ContentTool tool;
	private static ThreadLocal<Application> application = new ThreadLocal<Application>();
	protected Application app;

	private Content content;
	private LogoutListener logoutListener;

	public AdminMainLayout(Config toolConfig, Application app) {
		bb = new Blackboard();
		bb.register(LangChangedListener.class, LangChangedEvent.class);
		bb.register(MenuFragmentSelectedListener.class,
				MenuFragmentSelectedEvent.class);
		bb.register(MenuTagSelectedListener.class, MenuTagSelectedEvent.class);
		bb.register(PreviewCommittedListener.class, PreviewCommittedEvent.class);
		bb.register(MenuFilterListener.class, MenuFilterEvent.class);
		bb.register(ValueAddedListener.class, ValueAddedEvent.class);
		bb.register(TagsChangedListener.class, TagsChangedEvent.class);
		bb.register(VersionChangedListener.class, VersionChangedEvent.class);
		bb.register(LogoutInternalListener.class, LogoutInternalEvent.class);
		blackboard.set(bb);

		bb.addListener(this);

		tool = new ContentTool(toolConfig, new Locale("en"));
		contenttool.set(tool);

		this.app = app;
		application.set(app);
		app.getContext().addTransactionListener(this);

		setSizeFull();
		addStyleName("contenttool");

		Header h = new Header();
		bb.addListener(h);
		addComponent(h);

		HorizontalSplitPanel splitPanel = new HorizontalSplitPanel();
		splitPanel.setSizeFull();
		splitPanel.setSplitPosition(300, UNITS_PIXELS);
		splitPanel.addStyleName(Reindeer.SPLITPANEL_SMALL);
		addComponent(splitPanel);
		setExpandRatio(splitPanel, 1);

		MenuLayout menu = new MenuLayout();
		splitPanel.setFirstComponent(menu);

		content = new Content();
		splitPanel.setSecondComponent(content);
	}

	@Override
	public void transactionStart(Application application, Object transactionData) {
		if (application == app) {
			blackboard.set(bb);
			contenttool.set(tool);
			AdminMainLayout.application.set(app);
		}

	}

	@Override
	public void transactionEnd(Application application, Object transactionData) {
		if (application == app) {
			blackboard.set(null);
			contenttool.set(null);
			AdminMainLayout.application.set(null);
		}
	}

	public static Blackboard bb() {
		return blackboard.get();
	}

	public static ContentTool ct() {
		return contenttool.get();
	}

	public static Application app() {
		return application.get();
	}

	/**
	 * @see LogoutListener
	 */
	public LogoutListener getLogoutListener() {
		return logoutListener;
	}

	/**
	 * @see LogoutListener
	 */
	public void setLogoutListener(LogoutListener logoutListener) {
		this.logoutListener = logoutListener;
	}

	/**
	 * Listener to notify outside classes that the user has requested logout
	 * from the Admin UI. By default the logout button does nothing.
	 * 
	 * @author Thomas Mattsson / Vaadin OY
	 */
	public interface LogoutListener {
		public void logout();
	}

	@Override
	public void logoutRequested(LogoutInternalEvent event) {
		if (logoutListener != null) {
			logoutListener.logout();
		}
	}
}
